﻿using System;
using System.Web;
using System.IO;

using NVelocity;
using NVelocity.App;
using NVelocity.Context;
using NVelocity.Runtime;
using Commons.Collections;
using System.Text.RegularExpressions;
using FTchina;

/// <summary>
/// NVelocity模板工具类 VelocityHelper
/// </summary>
public class VelocityHelper
{
    private VelocityEngine velocity = null;
    private IContext context = null;
    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="templatDir">模板文件夹路径</param>
    public VelocityHelper(string templatDir)
    {
        Init(templatDir);
    }
    /// <summary>
    /// 无参数构造函数
    /// </summary>
    public VelocityHelper() { ;}
    /// <summary>
    /// 初始化NVelocity模块
    /// </summary>
    /// <param name="templatDir">模板文件夹路径</param>
    public void Init(string templatDir)
    {
 
        //创建VelocityEngine实例对象
        velocity = new VelocityEngine();
 
        //使用设置初始化VelocityEngine
        ExtendedProperties props = new ExtendedProperties();
 
        props.AddProperty(RuntimeConstants.RESOURCE_LOADER, "file");
 
        props.AddProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, basic.GetMapPath()+templatDir);
 
        props.AddProperty(RuntimeConstants.INPUT_ENCODING, "gb2312");
        props.AddProperty(RuntimeConstants.OUTPUT_ENCODING, "gb2312");
   
        velocity.Init(props);
 
       
        //为模板变量赋值
        context = new VelocityContext();
 
    }
    /// <summary>
    /// 给模板变量赋值
    /// </summary>
    /// <param name="key">模板变量</param>
    /// <param name="value">模板变量值</param>
    public void Put(string key, object value)
    {
        if (context == null)
            context = new VelocityContext();
        context.Put(key, value);
    }
    /// <summary>
    /// 显示模板
    /// </summary>
    /// <param name="templatFileName">模板文件名</param>
    public void Display(string templatFileName)
    {
        try
        {
            //从文件中读取模板
            Template template = velocity.GetTemplate(templatFileName);
            //合并模板
            StringWriter writer = new StringWriter();
            template.Merge(context, writer);

            string text = writer.ToString();

            text = _ProcessHeaderTags(text, "meta");
            text = _ProcessHeaderTags(text, "title");
            text = _ProcessHeaderTags(text, "link");

            text = Regex.Replace(text, "[\f\n\r\t\v]", "");
            text = Regex.Replace(text, " {2,}", " ");
            text = Regex.Replace(text, ">[ ]{1}", ">");
            text = Regex.Replace(text, @"[\n\r]", "");

            //输出
            HttpContext.Current.Response.Clear();
            HttpContext.Current.Response.Write(text);
            HttpContext.Current.Response.Flush();
            HttpContext.Current.Response.End();
        }
        catch
        {
            HttpContext.Current.Response.Redirect(String.Format(basic.GetSiteUrl() + "error.aspx?error={0}", 7700));
        }
    }


    /// <summary>
    /// 生成静态文件
    /// </summary>
    /// <param name="templatFileName">模板名称</param>
    /// <param name="Serverpath">保存地址，转化为c:\wwwroot\2208.html格式</param>
    public void CreatHtml(string templatFileName, string Serverpath)
    {
        object lckobj = new object();
        lock (lckobj)
        {
            //从文件中读取模板
            Template template = velocity.GetTemplate(templatFileName);

            //合并模板
            StringWriter writer = new StringWriter();
            template.Merge(context, writer);

            string text = writer.ToString();

            text = _ProcessHeaderTags(text, "meta");
            text = _ProcessHeaderTags(text, "title");
            text = _ProcessHeaderTags(text, "link");

            text = Regex.Replace(text, "[\f\n\r\t\v]", "");
            text = Regex.Replace(text, " {2,}", " ");
            text = Regex.Replace(text, ">[ ]{1}", ">");
            text = Regex.Replace(text, @"[\n\r]", "");

            using (StreamWriter sw = new StreamWriter(Serverpath, false, System.Text.Encoding.UTF8))
            {
                sw.Write(text);
                sw.Close();
            }
        }
    }

    /// <summary>
    /// 显示并生成html
    /// </summary>
    /// <param name="templatFileName"></param>
    /// <param name="Serverpath"></param>
    public void DisplayAndMake(string templatFileName, string Serverpath)
    {
        //从文件中读取模板
        Template template = velocity.GetTemplate(templatFileName);
        //合并模板
        StringWriter writer = new StringWriter();
        template.Merge(context, writer);

        string text = writer.ToString();

        text = _ProcessHeaderTags(text, "meta");
        text = _ProcessHeaderTags(text, "title");
        text = _ProcessHeaderTags(text, "link");



        text = Regex.Replace(text, "[\f\n\r\t\v]", "");
        text = Regex.Replace(text, " {2,}", " ");
        text = Regex.Replace(text, ">[ ]{1}", ">");
        text = Regex.Replace(text, @"[\n\r]", "");
 

        //写入文件
        using (StreamWriter sw = new StreamWriter(Serverpath, false, System.Text.Encoding.UTF8))
        {
            //写入到文件中	
            sw.Write(text);
            sw.Close();
        }
        //输出
        HttpContext.Current.Response.Clear();
        HttpContext.Current.Response.Write(text);
        HttpContext.Current.Response.Flush();
        HttpContext.Current.Response.End();
    }


    /// <summary>
    /// 整理页面特定标签，将页面内所有的指定标签整理到 head 区。
    /// </summary>
    /// <param name="text">要处理的模板内容。</param>
    /// <param name="tag">标签名。</param>
    /// <returns>string</returns>
    private string _ProcessHeaderTags(string text, string tag)
    {
        Regex re = new Regex(String.Format("(<{0}[^>]*?>)(.*</{0}>)?", tag), RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);
        MatchCollection mc = re.Matches(text);
        string list = "{$Tag}", item = "";
        int i = 0;

        foreach (Match m in mc)
        {
            i++;
            Group group = m.Groups[0];
            item = group.Value;

            if (list.IndexOf(item) == -1)
                list = list.Replace("{$Tag}", item.Trim() + "\r\n{$Tag}");

            if (i > 1)
                text = text.Replace(item, "");
            else
                text = text.Remove(group.Index, group.Length).Insert(group.Index, "{$TagPosition}");
        }

        text = Regex.Replace(text, @"(\{\$TagPosition})+?", list.Replace("{$Tag}", ""), RegexOptions.None);

        return text;
    }

}